package com.blog.serviceImpl;

import com.blog.NotFoundException;
import com.blog.dao.BlogDao;
import com.blog.entity.Blog;
import com.blog.service.BlogService;
import com.blog.util.MarkdownUtils;
import com.blog.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 博客列表业务层接口实现类
 */
@Service
public class BlogServiceImpl implements BlogService {

    @Autowired
    private BlogDao blogDao;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public ShowBlog getBlogById(Long id) {
        return blogDao.getBlogById(id);
    }

    @Override
    public List<BlogQuery> getAllBlog() {
        return blogDao.getAllBlogQuery();
    }

    @Override
    public List<BlogQuery> getArchiveBlog() {
        return blogDao.getArchiveBlog();
    }

    @Override
    public int saveBlog(Blog blog) {
        //初始化
        blog.setCreateTime(new Date());
        blog.setUpdateTime(new Date());
        blog.setViews(0);
        blog.setCommentCount(0);
        return blogDao.saveBlog(blog);
    }

    @Override
    public int updateBlog(ShowBlog showBlog) {
        showBlog.setUpdateTime(new Date());
        return blogDao.updateBlog(showBlog);
    }

    @Override
    public void deleteBlog(Long id) {
        blogDao.deleteBlog(id);
    }

    @Override
    public List<BlogQuery> getBlogBySearch(SearchBlog searchBlog) {
        return blogDao.searchByTitleOrTypeOrRecommend(searchBlog);
    }

    @Override
    public List<FirstPageBlog> getAllFirstPageBlog() {
        return blogDao.getFirstPageBlog();
    }

    @Override
    public List<RecommendBlog> getRecommendedBlog() {
        String key = "blog_recommand";
        ValueOperations<String, List<RecommendBlog>> operations = redisTemplate.opsForValue();
        List<RecommendBlog> recommendBlogList = operations.get(key);
        if(CollectionUtils.isEmpty(recommendBlogList)){
            recommendBlogList = blogDao.getAllRecommendBlog();
            operations.set(key,recommendBlogList,12,TimeUnit.HOURS);
        }
        return recommendBlogList;
    }

    @Override
    public List<FirstPageBlog> getSearchBlog(String query) {
        return blogDao.getSearchBlog(query);
    }

    /**
     * entity类po类太过于分散 故得设置缓存过期时间-否则DB更新后无法同步
     * @param id
     * @return
     */
    @Override
    public DetailedBlog getDetailedBlog(Long id) {
        //缓存key
        String key = "blog_detail:"+id;
        ValueOperations<String, DetailedBlog> operations = redisTemplate.opsForValue();
        //Redis 用了GET命令
        DetailedBlog detailedBlog = operations.get(key);
        if(detailedBlog == null){
            //若redis没有的话，直接去数据库捞
            detailedBlog = blogDao.getDetailedBlog(id);
            //重新set到redis，方便下次查找
            operations.set(key,detailedBlog,1,TimeUnit.DAYS);
        }

        if (detailedBlog == null) {
            throw new NotFoundException("该博客不存在");
        }
        String content = detailedBlog.getContent();
        //复制一份，修改内容时不会修改到数据库
//        Blog b = new Blog();
//        BeanUtils.copyProperties(detailedBlog,b);
        detailedBlog.setContent(MarkdownUtils.markdownToHtmlExtensions(content));   //博客内容格式转换


        /**
         * 文章访问数量自增
         * DB操作 blogDao.updateViews(id);  -> 改redis缓存＋定时任务持久化到mysql
         */
        ValueOperations<String,Integer> operationsNum = redisTemplate.opsForValue();
        String keyNum = "blog_num:"+id;
        operationsNum.increment(keyNum);

//        Integer valueNum = operationsNum.get(keyNum);
//        if(valueNum == null){   //将文章阅读量首次加入redis
//            operationsNum.set(keyNum,detailedBlog.getViews());
//        }else {
//            operationsNum.increment(keyNum);
//        }

        detailedBlog.setViews(operationsNum.get(keyNum)+detailedBlog.getViews());

        //文章评论数量更新
//        blogDao.getCommentCountById(id);
        return detailedBlog;
    }

    @Override
    public List<FirstPageBlog> getByTypeId(Long typeId) {
        return blogDao.getByTypeId(typeId);
    }

    @Override
    public int updateView(Long id, Integer views) {
        return blogDao.updateView(id,views);
    }

    @Override
    public Integer getBlogTotal() {
        return blogDao.getBlogTotal();
    }

    @Override
    public Integer getBlogViewTotal() {
        return blogDao.getBlogViewTotal();
    }

    @Override
    public Integer getBlogCommentTotal() {
        return blogDao.getBlogCommentTotal();
    }

    @Override
    public Integer getBlogMessageTotal() {
        return blogDao.getBlogMessageTotal();
    }

}